#ifndef COMMON_VEC3_H
#define COMMON_VEC3_H

#include "Common/Algebra/Misc.h"
#include "Common/Algebra/Vec2.h"

class Vec3 {
public:
	float X, Y, Z;

	Vec3( const float x, const float y, const float z ) : X( x ), Y( y ), Z( z ) {
	}

	Vec3( const Vec2& vec, float z ) : X( vec.X ), Y( vec.Y ), Z( z ) {
	}

	Vec3 operator +=(const Vec3& v );
	Vec3 operator -=(const Vec3& v );
	Vec3 operator *=(float a);
	Vec3 operator /=(float a);

	inline float Len( ) const {
		return (float) sqrt( Norm( ) );
	}

	inline float Norm( ) const {
		return (float) ( X * X + Y * Y + Z * Z );
	}

	Vec3 Normalize( );

	static const Vec3 ZERO;
	static const Vec3 UP;
	static const Vec3 DOWN;
	static const Vec3 LEFT;
	static const Vec3 RIGHT;
	static const Vec3 FORWARD;
	static const Vec3 BACK;
};

inline Vec3 operator-(const Vec3& v ) {
	return Vec3( -v.X, -v.Y, -v.Z );
}

inline Vec3 operator+(const Vec3& a, const Vec3& b ) {
	return Vec3( a.X + b.X, a.Y + b.Y, a.Z + b.Z );
}

inline Vec3 operator-(const Vec3& a, const Vec3& b ) {
	return Vec3( a.X - b.X, a.Y - b.Y, a.Z - b.Z );
}

inline Vec3 operator*(const Vec3& v, float a) {
	return Vec3( v.X * a, v.Y * a, v.Z * a );
}

inline Vec3 operator*(float a, const Vec3& v) {
	return Vec3( v.X * a, v.Y * a, v.Z * a );
}

inline Vec3 operator/(const Vec3& v, float a) {
	return Vec3( v.X / a, v.Y / a, v.Z / a );
}

inline Vec3 operator^ (const Vec3& a, const Vec3& b ) {
	return Vec3( a.Z * b.Y - a.Y * b.Z, a.X * b.Z - a.Z * b.X, a.Y * b.X - a.X * b.Y );
}

inline float operator*(const Vec3& a, const Vec3& b ) {
	return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
}

inline bool operator==(const Vec3& a, const Vec3& b ) {
	return a.X == b.X && a.Y == b.Y && a.Z == b.Z;
}

inline bool operator!=(const Vec3& a, const Vec3& b ) {
	return a.X != b.X || a.Y != b.Y || a.Z != b.Z;
}


#endif
